<?php
/*
+--------------------------------------------------------------------------
|   Anwsion [#RELEASE_VERSION#]
|   ========================================
|   by Tatfook Network Team
|   (c) 2011 - 2012 Anwsion Software
|   http://www.anwsion.com
|   ========================================
|   Support: zhengqiang@gmail.com
|   
+---------------------------------------------------------------------------
*/
/**
 * 返回浮点型的当前 Unix 时间戳和微秒数
 */
function microtime_float()
{
	list($usec, $sec) = explode(" ", microtime());
	return ((float)$usec + (float)$sec);
}

/**
 * 打印变量
 *
 * @param fixed $var
 */
if (! function_exists("p"))
{

	function p($var)
	{
		echo "<br><pre>";
		if (empty($var))
		{
			var_dump($var);
		}
		else
		{
			print_r($var);
		}
		
		echo "</pre><br>";
	}
}

/**
 * 打印变量 带 REQUEST["debugx"]==1
 *
 * @param fixed $var
 */
if (! function_exists("pd"))
{

	function pd($var, $exit = 0)
	{
		if ($_REQUEST["debugx"] == 1)
		{
			echo "<br><pre>";
			if (empty($var))
			{
				var_dump($var);
			}
			else
			{
				print_r($var);
			}
			
			echo "</pre><br>";
			if ($exit == 1)
				exit();
		}
	
	}
}

function aasort($array, $args)
{
	if (! $array)
	{
		return false;
	}
	
	$sort_rule = "";
	
	if ($args)
	{
		foreach ($args as $arg)
		{
			$order_field = substr($arg, 1, strlen($arg));
			
			foreach ($array as $array_row)
			{
				$sort_array[$order_field][] = $array_row[$order_field];
			}
			
			$sort_rule .= '$sort_array[' . $order_field . '], ' . ($arg[0] == "+" ? SORT_ASC : SORT_DESC) . ',';
		
		}
		
		eval("array_multisort($sort_rule" . ' $array);');
	}
	
	return $array;
}

/**
 * 获取用户IP
 *
 * @return string
 */
function real_ip()
{
	if (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
	{
		$onlineip = getenv('REMOTE_ADDR');
	}
	elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
	{
		$onlineip = $_SERVER['REMOTE_ADDR'];
	}
	elseif (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
	{
		$onlineip = getenv('HTTP_CLIENT_IP');
	}
	elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
	{
		$onlineip = getenv('HTTP_X_FORWARDED_FOR');
	}
	
	return $onlineip;
}

if (! function_exists('iconv'))
{

	function iconv($from_encoding = 'GBK', $target_encoding = 'UTF-8', $string)
	{
		convert_encoding($string, $from_encoding, $target_encoding);
	}
}

function convert_encoding($string, $from_encoding = 'GBK', $target_encoding = 'UTF-8')
{
	if (function_exists('mb_convert_encoding'))
	{
		return mb_convert_encoding($string, str_replace('//IGNORE', '', strtoupper($target_encoding)), $from_encoding);
	}
	else
	{
		if (strtoupper($target_encoding) == 'GB2312' OR strtoupper($target_encoding) == 'GBK')
		{
			$target_encoding .= '//IGNORE';
		}
		
		return iconv($from_encoding, $target_encoding, $string);
	}
}

function cjk_substr($string, $length, $dot = '...', $charset = 'UTF-8')
{
	if (cjk_strlen($string, $charset) <= $length)
	{
		return $string;
	}
	
	if (function_exists('mb_substr'))
	{
		return mb_substr($string, 0, $length, $charset) . $dot;
	}
	else
	{
		return iconv_substr($string, 0, $length, $charset) . $dot;
	}
}

function cjk_strlen($string, $charset = 'UTF-8')
{
	if (function_exists('mb_strlen'))
	{
		return mb_strlen($string, $charset);
	}
	else
	{
		return iconv_strlen($string, $charset);
	}
}

if (! function_exists('make_dir'))
{

	function make_dir($dir, $mode = 0777)
	{
		if (is_dir($dir) || @mkdir($dir, $mode))
		{
			return TRUE;
		}
		
		if (! make_dir(dirname($dir), $mode))
		{
			return FALSE;
		}
		
		return @mkdir($dir, $mode);
	}
}

if (! function_exists('mime_content_type'))
{

	function mime_content_type($filename)
	{
		
		$mime_types = array(
			
			'txt' => 'text/plain', 
			'htm' => 'text/html', 
			'html' => 'text/html', 
			'php' => 'text/html', 
			'css' => 'text/css', 
			'js' => 'application/javascript', 
			'json' => 'application/json', 
			'xml' => 'application/xml', 
			'swf' => 'application/x-shockwave-flash', 
			'flv' => 'video/x-flv', 
			
			// images
			'png' => 'image/png', 
			'jpe' => 'image/jpeg', 
			'jpeg' => 'image/jpeg', 
			'jpg' => 'image/jpeg', 
			'gif' => 'image/gif', 
			'bmp' => 'image/bmp', 
			'ico' => 'image/vnd.microsoft.icon', 
			'tiff' => 'image/tiff', 
			'tif' => 'image/tiff', 
			'svg' => 'image/svg+xml', 
			'svgz' => 'image/svg+xml', 
			
			// archives
			'zip' => 'application/zip', 
			'rar' => 'application/x-rar-compressed', 
			'exe' => 'application/x-msdownload', 
			'msi' => 'application/x-msdownload', 
			'cab' => 'application/vnd.ms-cab-compressed', 
			
			// audio/video
			'mp3' => 'audio/mpeg', 
			'qt' => 'video/quicktime', 
			'mov' => 'video/quicktime', 
			
			// adobe
			'pdf' => 'application/pdf', 
			'psd' => 'image/vnd.adobe.photoshop', 
			'ai' => 'application/postscript', 
			'eps' => 'application/postscript', 
			'ps' => 'application/postscript', 
			
			// ms office
			'doc' => 'application/msword', 
			'rtf' => 'application/rtf', 
			'xls' => 'application/vnd.ms-excel', 
			'ppt' => 'application/vnd.ms-powerpoint', 
			
			// open office
			'odt' => 'application/vnd.oasis.opendocument.text', 
			'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
		);
		
		$ext = strtolower(array_pop(explode('.', $filename)));
		if (array_key_exists($ext, $mime_types))
		{
			return $mime_types[$ext];
		}
		elseif (function_exists('finfo_open'))
		{
			$finfo = finfo_open(FILEINFO_MIME);
			$mimetype = finfo_file($finfo, $filename);
			finfo_close($finfo);
			return $mimetype;
		}
		else
		{
			return 'application/octet-stream';
		}
	}
}

function get_last_days($timestamp)
{
	if ($timestamp - time() <= 0)
	{
		return false;
	}
	
	$last_time = $timestamp - time();
	
	$last_day = $last_time / (3600 * 24);
	
	if (intval($last_day) < $last_day)
	{
		$last_day = intval($last_day) + 1;
	}
	
	return intval($last_day);
}

/**
 * 获取头像目录文件地址
 * @param  $uid
 * @param  $size
 * @param  $return_type 0=返回全部 1=返回目录(a/b/c/) 2=返回文件名
 * @return string
 */
function get_avatar_url($uid, $size = 'min', $avatar_file = null)
{
	$uid = $uid * 1;
	
	if ($uid < 1)
	{
		return "";
	}
	
	$size = in_array($size, array(
		'max', 
		'mid', 
		"50", 
		'min', 
		"150"
	)) ? $size : 'real';
	
	$uid = abs(intval($uid));
	$uid = sprintf("%09d", $uid);
	$dir1 = substr($uid, 0, 3);
	$dir2 = substr($uid, 3, 2);
	$dir3 = substr($uid, 5, 2);
	
	if ($avatar_file === null)
	{
		$avatar_file = AWS_APP::model("account")->get_avatar_file($uid);
	}
	
	if ($avatar_file === "")
	{
		return G_STATIC_URL . '/common/avatar-' . $size . '-img.jpg';
	}
	
	if (file_exists(get_setting('upload_dir') . '/avatar/' . $dir1 . '/' . $dir2 . '/' . $dir3 . '/' . substr($uid, - 2) . "_avatar_$size.jpg"))
	{
		return get_setting('upload_url') . '/avatar/' . $dir1 . '/' . $dir2 . '/' . $dir3 . '/' . substr($uid, - 2) . "_avatar_$size.jpg";
	}
	else
	{
		return G_STATIC_URL . '/common/avatar-' . $size . '-img.jpg';
	}
}

function jsonp_encode($json = array(), $callback = 'jsoncallback')
{
	if ($_GET[$callback])
	{
		return $_GET[$callback] . '(' . json_encode($json) . ')';
	}
	
	return json_encode($json);
}

function download_url($file_name, $url)
{
	$file_name = trim($file_name);
	$url = trim($url);
	
	if (! $file_name || ! $url)
	{
		return false;
	}
	
	return get_setting('base_url') . '/' . G_INDEX_SCRIPT . "file/re_download/file_name-" . base64_encode($file_name) . "__url-" . base64_encode($url);

}

function date_friendly($timestamp, $time_limit = 604800, $out_format = 'Y-m-d H:i', $formats = null, $time_now = null)
{
	if ($formats == null)
	{
		$formats = array(
			'YEAR' => '%s 年前', 
			'MONTH' => '%s 月前', 
			'DAY' => '%s 天前', 
			'HOUR' => '%s 小时前', 
			'MINUTE' => '%s 分钟前', 
			'SECOND' => '%s 秒前'
		);
	}
	
	$time_now = $time_now == null ? time() : $time_now;
	$seconds = $time_now - $timestamp;
	
	if ($time_limit != null && $seconds > $time_limit)
	{
		return date($out_format, $timestamp);
	}
	
	$minutes = floor($seconds / 60);
	$hours = floor($minutes / 60);
	$days = floor($hours / 24);
	$months = floor($days / 30);
	$years = floor($months / 12);
	
	if ($years > 0)
	{
		$diffFormat = 'YEAR';
	}
	else
	{
		if ($months > 0)
		{
			$diffFormat = 'MONTH';
		}
		else
		{
			if ($days > 0)
			{
				$diffFormat = 'DAY';
			}
			else
			{
				if ($hours > 0)
				{
					$diffFormat = 'HOUR';
				}
				else
				{
					$diffFormat = ($minutes > 0) ? 'MINUTE' : 'SECOND';
				}
			}
		}
	}
	
	$dateDiff = null;
	
	switch ($diffFormat)
	{
		case 'YEAR' :
			$dateDiff = sprintf($formats[$diffFormat], $years);
			break;
		case 'MONTH' :
			$dateDiff = sprintf($formats[$diffFormat], $months);
			break;
		case 'DAY' :
			$dateDiff = sprintf($formats[$diffFormat], $days);
			break;
		case 'HOUR' :
			$dateDiff = sprintf($formats[$diffFormat], $hours);
			break;
		case 'MINUTE' :
			$dateDiff = sprintf($formats[$diffFormat], $minutes);
			break;
		case 'SECOND' :
			$dateDiff = sprintf($formats[$diffFormat], $seconds);
			break;
	}
	
	return $dateDiff;
}

function &load_class($class)
{
	static $_classes = array();
	
	// Does the class exist?  If so, we're done...
	if (isset($_classes[$class]))
	{
		return $_classes[$class];
	}
	
	if (class_exists($class) === FALSE)
	{
		$file = AWS_PATH . preg_replace('#_+#', '/', $class) . '.php';
		
		if (! file_exists($file))
		{
			show_error('Unable to locate the specified class: ' . $class . ' ' . preg_replace('#_+#', '/', $class) . '.php');
		}
		
		require_once $file;
	}
	
	$_classes[$class] = new $class();
	
	return $_classes[$class];
}

function _show_error($errorMessage = '')
{
	$errorBlock = '';
	$name = strtoupper($_SERVER['HTTP_HOST']);
	
	if ($errorMessage)
	{
		$errorMessage = htmlspecialchars($errorMessage);
		$errorBlock = <<<EOF
		<div class='database-error'>
	    	<form name='mysql'>
	    		<textarea rows="15" cols="60">{$errorMessage}</textarea>
	    	</form>
    	</div>
EOF;
	}
	
	if (defined('IN_AJAX'))
	{
		return $errorMessage;
	}
	
	return <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
		<meta http-equiv="Pragma" content="no-cache" />
		<meta http-equiv="Cache-Control" content="no-cache" />
		<meta http-equiv="Expires" content="Fri, 01 January 1999 01:00:00 GMT" />
		<title>{$name} System Error</title>
		<style type='text/css'>
			body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { margin:0; padding:0; } 
			table {	border-collapse:collapse; border-spacing:0; }
			fieldset,img { border:0; }
			address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
			ol,ul { list-style:none; }
			caption,th { text-align:left; }
			h1,h2,h3,h4,h5,h6 { font-size:100%;	font-weight:normal; }
			q:before,q:after { content:''; }
			abbr,acronym { border:0; }
			hr { display: none; }
			address{ display: inline; }
			body {
				font-family: arial, tahoma, sans-serif;
				font-size: 0.8em;
				width: 100%;
			}
			
			h1 {
				font-family: arial, tahoma, "times new roman", serif;
				font-size: 1.9em;
				color: #fff;
			}
			h2 {
				font-size: 1.6em;
				font-weight: normal;
				margin: 0 0 8px 0;
				clear: both;
			}
			a {
				color: #3e70a8;
			}
			
				a:hover {
					color: #3d8ce4;
				}
				
				a.cancel {
					color: #ad2930;
				}
			#branding {
				background: #484848;
				padding: 8px;
			}
			
			#content {
				clear: both;
				overflow: hidden;
				padding: 20px 15px 0px 15px;
			}
			
			* #content {
				height: 1%;
			}
			
			.message {
				border-width: 1px;
				border-style: solid;
				border-color: #d7d7d7;
				background-color: #f5f5f5;
				padding: 7px 7px 7px 30px;
				margin: 0 0 10px 0;
				clear: both;
			}
			
				.message.error {
					background-color: #f3dddd;
					border-color: #deb7b7;
					color: #281b1b;
					font-size: 1.3em;
					font-weight: bold;
				}
				
				.message.unspecific {
					background-color: #f3f3f3;
					border-color: #d4d4d4;
					color: #515151;
				}
			.footer {
				text-align: center;
				font-size: 1.5em;
			}
			
			.database-error {
				padding: 4px 0px 10px 80px;
				margin: 10px 0px 10px 0px;
			}
			
			textarea {
				width: 700px;
				height: 250px;
			}
		</style>
	</head>
	<body id='ipboard_body'>
		<div id='header'>
			<div id='branding'>
				<h1>{$name} System Error</h1>
			</div>
		</div>
		<div id='content'>
			<div class='message error'>
				There appears to be an error:
				{$errorBlock}
			</div>
			
			<p class='message unspecific'>
				If you are seeing this page, it means there was a problem communicating with our database.  Sometimes this error is temporary and will go away when you refresh the page.  Sometimes the error will need to be fixed by an administrator before the site will become accessible again.
				<br /><br />
				You can try to refresh the page by clicking <a href="#" onclick="window.location=window.location; return false;">here</a>
			</p>
		</div>
	</body>
</html>
EOF;
}

function show_error($errorMessage = '')
{
	echo _show_error($errorMessage);
	exit();
}

function get_table($name)
{
	return AWS_APP::config()->get('database')->prefix . $name;
}

function array_unset_null_value($array)
{
	if ($array)
	{
		foreach ($array as $key => $val)
		{
			if (! $val)
			{
				unset($array[$key]);
			}
		}
	}
	return $array;
}

function get_setting($varname = '')
{
	static $setting;
	
	if (! $setting)
	{
		if (file_exists(AWS_PATH . 'config/setting.php'))
		{
			$setting = (array)load_class('core_config')->get('setting');
		}
		else
		{
			if ($result = AWS_APP::db()->fetchAll(AWS_APP::db()->select()->from(get_table('system_setting'), '*')))
			{
				foreach ($result as $key => $val)
				{
					$setting[$val['varname']] = unserialize($val['value']);
				}
				
				//生成缓存文件
				AWS_APP::config()->set('setting', $setting);
			}
		}
		
		if ($setting['upload_enable'] == 'Y' && ! $_SESSION['permission']['upload_attach'])
		{
			$setting['upload_enable'] = 'N';
		}
	}
	
	if ($varname)
	{
		return $setting[$varname];
	}
	else
	{
		return $setting;
	}
}

// ------------------------------------------------------------------------


/**
 * Tests for file writability
 *
 * is_writable() returns TRUE on Windows servers when you really can't write to 
 * the file, based on the read-only attribute.  is_writable() is also unreliable
 * on Unix servers if safe_mode is on. 
 *
 * @return	void
 */
function is_really_writable($file)
{
	// If we're on a Unix server with safe_mode off we call is_writable
	if (DIRECTORY_SEPARATOR == '/' and @ini_get("safe_mode") == FALSE)
	{
		return is_writable($file);
	}
	
	// For windows servers and safe_mode "on" installations we'll actually
	// write a file then read it.  Bah...
	if (is_dir($file))
	{
		$file = rtrim($file, '/') . '/' . md5(rand(1, 100));
		
		if (! @file_put_contents($file, 'is_really_writable() test.'))
		{
			return FALSE;
		}
		else
		{
			@unlink($file);
		}
		
		return TRUE;
	}
	else if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
	{
		return FALSE;
	}
	
	return TRUE;
}

/**
 * 生成密码种子的函数
 *
 * @access      private
 * @param       int     length        长度
 * @return      string
 */
function fetch_salt($length = 4)
{
	$salt = '';
	for ($i = 0; $i < $length; $i ++)
	{
		$salt .= chr(rand(97, 122));
	}
	
	return $salt;
}

/**
 * 编译密码
 *
 *  @param  $password 	密码
 *  @param  $salt		混淆码
 * 	@return string		加密后的密码
 */
function compile_password($password, $salt)
{
	if (strlen($password) == 32)
	{
		return $password;
	}
	
	$password = md5(md5($password) . $salt);
	
	return $password;
}

/**
 * 创建 REWRITE 的 URL
 * @param  $app_dir
 * @param  $controller
 * @param  $action
 * @param  $args
 */
function get_rewrite($app_dir, $controller, $action, $args = array(), $args_att = "")
{
	$app_dir = trim($app_dir);
	$controller = trim($controller);
	$action = trim($action);
	$url = "";
	
	if ($args)
	{
		foreach ($args as $key => $val)
		{
			$args_str[] = $key . $this->params['sep_value'] . $val;
		}
	}
	
	if (is_array($args_str))
	{
		$url = implode($this->params['sep_var'], $args_str);
	}
	
	$url = G_INDEX_SCRIPT . $app_dir . $this->params['sep_act'] . $controller . $this->params['sep_act'] . $action . $this->params['sep_act'] . $url;
	//.$this->params['suffix'];
	

	if ($args_att != "")
	{
		$url = $url . $this->params['suffix'] . "?" . $args_att;
	}
	
	$url = get_setting('base_url') . "/" . $url;
	
	return $url;
}

function get_js_url($url)
{
	if (substr($url, 0, 1) == '/')
	{
		$url = get_setting('base_url') . '/' . G_INDEX_SCRIPT . substr($url, 1);
	}
	
	return $url;
}

function calc_page_limit($page, $pre_page)
{
	if ($page < 1)
	{
		$page = 1;
	}
	
	return ((intval($page) - 1) * $pre_page) . ', ' . $pre_page;
}

function clear_point($bd)
{
	return str_replace(array(
		"~", 
		"!", 
		"@", 
		"#", 
		"$", 
		"%", 
		"^", 
		"&", 
		"*", 
		",", 
		".", 
		"?", 
		";", 
		":", 
		"'", 
		'"', 
		"[", 
		"]", 
		"{", 
		"}", 
		"！", 
		" ￥", 
		"……", 
		"…", 
		"、", 
		"，", 
		"。", 
		"？", 
		"；", 
		"：", 
		"‘", 
		"“", 
		"”", 
		"’", 
		" 【", 
		"】", 
		"～", 
		"！", 
		"＠", 
		"＃", 
		"＄", 
		"％", 
		"＾", 
		"＆", 
		"＊", 
		"，", 
		"．", 
		" ＜", 
		"＞", 
		"；", 
		"：", 
		"＇", 
		"＂", 
		"［", 
		"］", 
		"｛", 
		"｝", 
		"／", 
		"＼"
	), '', $bd);
}

function get_login_cookie_hash($user_name, $password, $salt, $user_id)
{
	$hash_cookie['user_name'] = $user_name;
	$hash_cookie['password'] = compile_password($password, $salt);
	$hash_cookie['uid'] = intval($user_id);
	$hash_cookie['UA'] = $_SERVER['HTTP_USER_AGENT'];
	
	return H::encode_hash($hash_cookie);
}

function random($length, $numeric = 0)
{
	//PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
	
	if ($numeric)
	{
		$hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) - 1));
	}
	else
	{
		$hash = '';
		$chars = '0123456789abcdefghijklmnopqrstuvwxyz';
		$max = strlen($chars) - 1;
		
		for ($i = 0; $i < $length; $i ++)
		{
			$hash .= $chars[mt_rand(0, $max)];
		}
	}
	
	return $hash;
}

function valid_post_hash($hash)
{
	return AWS_APP::form()->valid_post_hash($hash);
}

function new_post_hash()
{
	return AWS_APP::form()->new_post_hash();
}

// 检测当前操作是否需要验证码
function human_valid($permission_tag)
{
	if (! is_array($_SESSION['human_valid']))
	{
		return FALSE;
	}
	
	if (! $_SESSION['human_valid'][$permission_tag] or ! $_SESSION['permission'][$permission_tag])
	{
		return FALSE;
	}
	
	foreach ($_SESSION['human_valid'][$permission_tag] as $time => $val)
	{
		if (date('H', $time) != date('H', time()))
		{
			unset($_SESSION['human_valid'][$permission_tag][$time]);
		}
	}
	
	if (sizeof($_SESSION['human_valid'][$permission_tag]) >= $_SESSION['permission'][$permission_tag])
	{
		return TRUE;
	}
	
	return FALSE;
}

function set_human_valid($permission_tag)
{
	if (! is_array($_SESSION['human_valid']))
	{
		return FALSE;
	}
	
	$_SESSION['human_valid'][$permission_tag][time()] = TRUE;
	
	return count($_SESSION['human_valid'][$permission_tag]);
}